package com.google.project.client.ProjectManager;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.project.client.Service.ProjTaskService;
import com.google.project.client.Service.ProjTaskServiceAsync;
import com.google.project.client.Service.ProjectService;
import com.google.project.client.Service.ProjectServiceAsync;
import com.google.project.shared.CommonFuntion;
import com.google.project.shared.ProjectTaskDTO;
import com.google.gwt.user.client.ui.ScrollPanel;

public class tree extends DialogBox {

	private static final Binder binder = GWT.create(Binder.class);
	@UiField Tree tree;
	@UiField Button button;
	@UiField ScrollPanel scoll;
	@UiField Button button_1;
   
	interface Binder extends UiBinder<Widget, tree> {
	}
	ProjectTaskDTO mainTask = new ProjectTaskDTO();
	int numOfDate ;
	private List<ProjectTaskDTO> listTask = new ArrayList<ProjectTaskDTO>();
	private List<ProjectTaskDTO> listMistone = new ArrayList<ProjectTaskDTO>();
	private final ProjectServiceAsync projectService = GWT.create(ProjectService.class);
	private final ProjTaskServiceAsync projectTaskService = GWT.create(ProjTaskService.class);
	
	public tree() {
		setWidget(binder.createAndBindUi(this));
		
		for(int i =1;i<5;i++)
		{
			 CellTable<ProjectTaskDTO> data = new CellTable<ProjectTaskDTO>();
			 List<ProjectTaskDTO> listTask = new ArrayList<ProjectTaskDTO>();
				for(int j=0;j<=3;j++)
				{
				ProjectTaskDTO task = new ProjectTaskDTO();
				task.setTaskName("cong viec "+(j+1));
				Date date = new Date();
				task.setStartDate(date.getTime());
				task.setDueDate(date.getTime());
				task.setAmountOfWork(1000d);
				task.setUnit("M");
				listTask.add(task);
				}
				initTable(data);
				LoadDataForTable(listTask, data);
				TreeItem outerRoot2 = new TreeItem(new CheckBox("muc " +i));
				outerRoot2.addItem(data);
				outerRoot2.setUserObject(listTask);
				tree.addItem(outerRoot2);
		}
 
	}
	
	void drawTree( TreeItem item,ProjectTaskDTO data ,Long dateDiff2)
	{
				String afterData="";
				if(data.getDependent()!=null&&!data.getDependent().equals(""))
				{
					afterData = data.getDependent().substring(data.getDependent().indexOf("|"));
					
					if(afterData.length()>1)
					{
						afterData=afterData.substring(1);
					}
					else
					{
						afterData="";
					}
				}
				if(!afterData.equals(""))
				{
					for(ProjectTaskDTO temp : listTask)
					{
						Long checkDate = CommonFuntion.removeTime(new Date(data.getDueDate()));
						 checkDate =  checkDate +  dateDiff2;
						 String checkDate1 = CommonFuntion.convertToDate(new Date(checkDate));
						 Long compareDate = CommonFuntion.removeTime(new Date(temp.getStartDate()));
							String compareDate1 = CommonFuntion.convertToDate(new Date(compareDate));
							Long dateDiff = checkDate-compareDate + 24*60*60*1000;
						 //check
						 if(compareDate>checkDate)
						 {
							 continue;
						 }
						if(CommonFuntion.checkContain(afterData,temp.getTaskId()+""))
						{
							 TreeItem itemChild=	new TreeItem(new CheckBox(temp.getTaskName()+" | Bắt đầu : "+CommonFuntion.convertToDate(new Date(temp.getStartDate()))+" | Kết thúc : "+CommonFuntion.convertToDate(new Date(temp.getDueDate()))+"| Số ngày thay đổi: "+(dateDiff/(24*60*60*1000))+" | Khối lượng : " + temp.getAmountOfWork()+" "+temp.getUnit()));
							// TreeItem itemChild= 	new TreeItem(new CheckBox(temp.getTaskName()+" | Bắt đầu : "+CommonFuntion.convertToDate(new Date(temp.getStartDate()))+" | Kết thúc cũ: "+CommonFuntion.convertToDate(new Date(temp.getDueDate()))+" | Kết thúc mới: "+CommonFuntion.convertToDate(new Date(temp.getDueDate()+dateDiff))+" | Khối lương : " + temp.getAmountOfWork()+" "+temp.getUnit()));
							 itemChild.setUserObject(temp);
							 if(temp.getParentId()!=0)
								{
									ProjectTaskDTO parent = getTaskFromList(temp.getParentId());
									//kiem tra co thoi gian khi thai doi co vuot qua thoi gian cha ko
									if( CommonFuntion.removeTime(new Date(temp.getDueDate()))+(checkDate-compareDate) >CommonFuntion.removeTime(new Date(parent.getDueDate())))
									{
										item.addItem(itemChild);
									}
									else
									{//neu ko vuot qua ve tiep cac buoc tiep theo
										
										if(checkMistoneForTask(temp, dateDiff))
										{
											 drawTree(itemChild,temp,dateDiff);
											 item.addItem(itemChild);
										}
										else
										{
											item.addItem(itemChild);
										}
										
									}
								}
							 else
							 {
								 if(checkMistoneForTask(temp, dateDiff))
									{
										 drawTree(itemChild,temp,dateDiff);
										 item.addItem(itemChild);
									}
								 else
									{
										item.addItem(itemChild);
									}
							 }
							 //list.add(temp);
						}
					}
				}
		
	}
	ProjectTaskDTO getTaskFromList(int taskId)
	{
		ProjectTaskDTO task = new ProjectTaskDTO();
		for(ProjectTaskDTO data: listTask)
		{
			if(data.getTaskId()==taskId)
			{
				task =data;
			}
		}
		return task;
	}
	void getAterLevel2(ProjectTaskDTO data)
	{
			String afterData="";
			 TreeItem root=	new TreeItem(new HTML("<h5>"+data.getTaskName()+" | Bắt đầu : "+CommonFuntion.convertToDate(new Date(data.getStartDate()))+" | Kết thúc cũ: "+CommonFuntion.convertToDate(new Date(data.getDueDate()))+" | Kết thúc mới: "+CommonFuntion.convertToDate(new Date(data.getDueDate()+numOfDate*24*60*60*1000))+" | Khối lượng : " + data.getAmountOfWork()+" "+data.getUnit()+"</h5>"));
			 tree.addItem(root);
			 data.setDueDate(data.getDueDate()+numOfDate*24*60*60*1000);
			 if(data.getDependent()!=null&&!data.getDependent().equals(""))
			{
				afterData = data.getDependent().substring(data.getDependent().indexOf("|"));
				
				if(afterData.length()>1)
				{
					afterData=afterData.substring(1);
				}
				else
				{
					afterData="";
				}
			}
			if(!afterData.equals(""))
			{
				
				for(ProjectTaskDTO temp : listTask)
				{
					if(CommonFuntion.checkContain(afterData,temp.getTaskId()+""))
					{
						
						Long checkDate = CommonFuntion.removeTime(new Date(data.getDueDate()));
						String checkDate1 = CommonFuntion.convertToDate(new Date(checkDate));
						Long compareDate = CommonFuntion.removeTime(new Date(temp.getStartDate()));
						String compareDate1 = CommonFuntion.convertToDate(new Date(compareDate));
						Long dateDiff = checkDate-compareDate + 24*60*60*1000;
						//neu thoi gian ket thuc cua cong viec cha khong anh huong den thoi gian bat dau  cv con tiep tuc
						//check
						if(compareDate>checkDate)
						 {
							 continue;
						 }
					//	 TreeItem item=	new TreeItem(new CheckBox(temp.getTaskName()+" | Bắt đầu : "+CommonFuntion.convertToDate(new Date(temp.getStartDate()))+" | Kết thúc cũ : "+CommonFuntion.convertToDate(new Date(temp.getDueDate()))+" | Kết thúc mới : "+CommonFuntion.convertToDate(new Date(temp.getDueDate()+dateDiff))+" | Khối lương : " + temp.getAmountOfWork()+" "+temp.getUnit()));
						 
				 TreeItem item=	new TreeItem(new CheckBox(temp.getTaskName()+" | Bắt đầu : "+CommonFuntion.convertToDate(new Date(temp.getStartDate()))+" | Kết thúc : "+CommonFuntion.convertToDate(new Date(temp.getDueDate()))+"| Số ngày thay đổi: "+(dateDiff/(24*60*60*1000)) +" | Khối lượng : " + temp.getAmountOfWork()+" "+temp.getUnit()));
						item.setUserObject(temp);
						 //neu co bo
						 if(temp.getParentId()!=0)
						{
							ProjectTaskDTO parent = getTaskFromList(temp.getParentId());
							//kiem tra co thoi gian khi thai doi co vuot qua thoi gian cha ko
							if( CommonFuntion.removeTime(new Date(temp.getDueDate()))+(checkDate-compareDate) >CommonFuntion.removeTime(new Date(parent.getDueDate())))
							{
								root.addItem(item);
							}
							else
							{//neu ko vuot qua ve tiep cac buoc tiep theo
								if(checkMistoneForTask(temp, dateDiff))
								{
									 drawTree(item,temp,dateDiff);
									 root.addItem(item);
								}else
								{
									root.addItem(item);
								}
								
							}
						}
						else
						{
							if(checkMistoneForTask(temp, dateDiff))
							{
								 drawTree(item,temp,dateDiff);
								 root.addItem(item);
							}else
							{
								root.addItem(item);
							}
						}
						
					}
				}
			}
	}

	Boolean getDataCheckedFromChild(List<ProjectTaskDTO>  result ,TreeItem root)
	{
		int count =0;
		Boolean check = false;
		for(int i = 0;i<root.getChildCount();i++)
		{
			
			TreeItem item = root.getChild(i); 
		    CheckBox itemCheckBox = (CheckBox)item.getWidget();
		    boolean checkBoxValue = itemCheckBox.getValue().booleanValue();
			if(checkBoxValue)
			{
				ProjectTaskDTO itemData = (ProjectTaskDTO)( item.getUserObject());
				//?
			
				result.add(itemData);
				count++;
				if(count==root.getChildCount())
				{
					check = true;
				}
			}
			else
			{
				check= getDataCheckedFromChild( result ,item);
				if(check ==false)
				{
					return check;
				}
			}
		}
		return check;
	}
	List<ProjectTaskDTO> getDataChecked()
	{
		List<ProjectTaskDTO> list = new  ArrayList<ProjectTaskDTO>();
		int count =0;
		Boolean check = false;
		TreeItem root = tree.getItem(0); 
		for(int i = 0;i<root.getChildCount();i++)
		{
			TreeItem item = root.getChild(i); 
		    CheckBox itemCheckBox = (CheckBox)item.getWidget();
		    boolean checkBoxValue = itemCheckBox.getValue().booleanValue();
			if(checkBoxValue)
			{
				ProjectTaskDTO itemData = (ProjectTaskDTO)( item.getUserObject());
				list.add(itemData);
				count++;
				if(count==root.getChildCount())
				{
					check = true;
				}
			}
			else
			{
				check = getDataCheckedFromChild(  list ,item);
				if(check ==false)
				{
					Window.alert("Chưa chọn đủ công việc cần thiết");
					return null;
				}
			}
		}
		return list;
	}
	
	
	public tree(ProjectTaskDTO data , int dateDiff) {
		mainTask = data;
		numOfDate = dateDiff;
		setWidget(binder.createAndBindUi(this));
	
		projectTaskService.getListOrderTaskByProjectId(mainTask.getProjectId(), new AsyncCallback<List<ProjectTaskDTO>>() {
			
			@Override
			public void onSuccess(List<ProjectTaskDTO> result) {
				// TODO Auto-generated method stub
				listTask = result;
				for(ProjectTaskDTO task:listTask )
				{
					if(task.getIsMile()==1)
					{
						listMistone.add(task);
					}
				}
				getAterLevel2(mainTask);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		});
		
	}

	
	Boolean checkMistoneForTask(ProjectTaskDTO task,Long dateDiff)
	{
		for(ProjectTaskDTO mistone :listMistone)
		{

			if(CommonFuntion.removeTime(new Date(task.getDueDate()))<= CommonFuntion.removeTime(new Date(mistone.getStartDate())))
			{
				if(CommonFuntion.removeTime(new Date(task.getDueDate()+dateDiff))< CommonFuntion.removeTime(new Date(mistone.getStartDate())))
				{
					return true;
				}
				return false;
			}
			
		}
		return true;
	}
	 public void initTable( CellTable<ProjectTaskDTO> ctbTask)
	 {
				TextColumn<ProjectTaskDTO> stt = new TextColumn<ProjectTaskDTO>() {
					@Override
					public String getValue(ProjectTaskDTO task) {
						return task.getSTT();
					}
				};
			@SuppressWarnings("unused")
			TextColumn<ProjectTaskDTO> taskName = new TextColumn<ProjectTaskDTO>() {
				@Override
				public String getValue(ProjectTaskDTO task) {
					return task.getTaskName();
				}
			};

			TextColumn<ProjectTaskDTO> startDate = new TextColumn<ProjectTaskDTO>() {
				@SuppressWarnings("deprecation")
				@Override
				public String getValue(ProjectTaskDTO task) {
					Date startDate = new Date(task.getStartDate());
					return startDate.getDate() + "/" + (startDate.getMonth() + 1)
							+ "/" + (startDate.getYear() + 1900);
				}
			};
			TextColumn<ProjectTaskDTO> dueDate = new TextColumn<ProjectTaskDTO>() {
				@SuppressWarnings("deprecation")
				@Override
				public String getValue(ProjectTaskDTO task) {
					Date dueDate = new Date(task.getDueDate());
					return dueDate.getDate() + "/" + (dueDate.getMonth() + 1) + "/"
							+ (dueDate.getYear() + 1900);
				}
			};
			TextColumn<ProjectTaskDTO> amountOfWork = new TextColumn<ProjectTaskDTO>() {
				@Override
				public String getValue(ProjectTaskDTO task) {
					return task.getAmountOfWork().toString()+ " "+task.getUnit();
				}
			};
			
			TextColumn<ProjectTaskDTO> weight = new TextColumn<ProjectTaskDTO>() {
				@Override
				public String getValue(ProjectTaskDTO task) {
					return task.getWeight().toString()+" %";
				}
			};


			Column<ProjectTaskDTO, String> taskNameColumn = new Column<ProjectTaskDTO, String>(
					new ClickableTextCell()) {
				@Override
				public String getValue(ProjectTaskDTO object) {
					return object.getTaskName();
				}
			};
			taskNameColumn
			.setFieldUpdater(new FieldUpdater<ProjectTaskDTO, String>() {

				@Override
				public void update(int index, ProjectTaskDTO task,
						String value) {
				//	PMEntrypoint.get().PMProjectTask(task.getId(),projectID);
				}

			});
		
			taskNameColumn.setCellStyleNames("celltable");
			
            ctbTask.setStyleName("ttable");
            ctbTask.addColumn(stt, "STT");
            ctbTask.addColumn(taskNameColumn, "Tên công việc");
            ctbTask.setColumnWidth(taskNameColumn, 25, Unit.PCT);
            ctbTask.addColumn(amountOfWork, "Khối lượng");
            ctbTask.addColumn(startDate, "Ngày bắt đầu");
            ctbTask.addColumn(dueDate, "Hạn kết thúc");
	 }
	
	void closeDialog()
	{
		this.hide();
	}
	@UiHandler("button")
	void onButtonClick(ClickEvent event) {
		this.hide();
		PMEntrypoint.get().PMCreateProjectPlan(mainTask.getProjectId());
	}
	
	//update
	@UiHandler("button_1")
	void onButton_1Click(ClickEvent event) {
		List<ProjectTaskDTO> list = new  ArrayList<ProjectTaskDTO>();
		list =getDataChecked();
		if(list!=null)
		{
			projectTaskService.updatePlan(mainTask, list, new AsyncCallback<Void>() {
				
				@Override
				public void onSuccess(Void result) {
					// TODO Auto-generated method stub
					Window.alert("Cập nhập thành công");
					closeDialog();
					PMEntrypoint.get().callPop(mainTask.getProjectId());
					
				}
				
				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}
			});
		}
	}
	
	void getAterLevel(List<ProjectTaskDTO> data,int level)
	{
		List<ProjectTaskDTO> list = new  ArrayList<ProjectTaskDTO>();
		List<ProjectTaskDTO> noAfter = new  ArrayList<ProjectTaskDTO>();
		
		for(ProjectTaskDTO task: data)
		{
			String afterData="";
			if(task.getDependent()!=null&&!task.getDependent().equals(""))
			{
				afterData = task.getDependent().substring(task.getDependent().indexOf("|"));
				
				if(afterData.length()>1)
				{
					afterData=afterData.substring(1);
				}
				else
				{
					afterData="";
				}
			}
			if(!afterData.equals(""))
			{
				for(ProjectTaskDTO temp : listTask)
				{
					if(CommonFuntion.checkContain(afterData,temp.getTaskId()+""))
					{
						list.add(temp);
					}
				}
			}
			else
			{
				noAfter.add(task);
			}
			
		}
		if(list.size()>0)
		{
			for(ProjectTaskDTO leafTask :noAfter )
			{
				list.add(leafTask);
				
			}
			 CellTable<ProjectTaskDTO> table = new CellTable<ProjectTaskDTO>();
			 initTable(table);
			 LoadDataForTable(list, table);
			 TreeItem outerRoot2 = new TreeItem(new CheckBox("Mức " +level));
				outerRoot2.addItem(table);
				outerRoot2.setUserObject(list);
		
				tree.addItem(outerRoot2);
				getAterLevel(list,level+1);
		}
	}
public void LoadDataForTable(List<ProjectTaskDTO> taskList,CellTable<ProjectTaskDTO> ctbTask) {
		
		ListDataProvider<ProjectTaskDTO> dataProvider = new ListDataProvider<ProjectTaskDTO>();
		dataProvider.addDataDisplay(ctbTask);

		// Add the data to the data provider, which automatically pushes it to
		// the widget
		// SimplePager
		//pager.setDisplay(ctbTask);
		//pager.setPageSize(5);
		int count =1;
		List<ProjectTaskDTO> list = dataProvider.getList();
		for (ProjectTaskDTO task : taskList) {
			task.setSTT(count+"");
			count ++;
			list.add(task);
			
		}
	}

}
